#define PI 3.14159265

#ifdef D3D9_IMPL

#else    

#define D3D10_CULL_NONE		1
#define D3D10_CULL_FRONT	2
#define D3D10_CULL_BACK		3

#define D3D10_BLEND_ZERO 1
#define D3D10_BLEND_ONE 2
#define D3D10_BLEND_SRC_COLOR 3
#define D3D10_BLEND_INV_SRC_COLOR 4
#define D3D10_BLEND_SRC_ALPHA 5
#define D3D10_BLEND_INV_SRC_ALPHA 6
#define D3D10_BLEND_DEST_ALPHA 7
#define D3D10_BLEND_INV_DEST_ALPHA 8
#define D3D10_BLEND_DEST_COLOR 9
#define D3D10_BLEND_INV_DEST_COLOR 10
#define D3D10_BLEND_SRC_ALPHA_SAT 11
#define D3D10_BLEND_BLEND_FACTOR 14
#define D3D10_BLEND_INV_BLEND_FACTOR 15
#define D3D10_BLEND_SRC1_COLOR 16
#define D3D10_BLEND_INV_SRC1_COLOR 17
#define D3D10_BLEND_SRC1_ALPHA 18
#define D3D10_BLEND_INV_SRC1_ALPHA 19
#endif

#ifndef LIB_STANDARD_FXH
#define LIB_STANDARD_FXH

Texture2D g_tex0;
sampler2D g_sam0 = sampler_state
{
	texture = g_tex0;
	Filter = MIN_MAG_MIP_LINEAR;
	AddressU = WRAP;
	AddressV = WRAP;
};

Texture2D g_tex1;
sampler2D g_sam1 = sampler_state
{
	texture= g_tex1;
	Filter = MIN_MAG_MIP_LINEAR;
	AddressU = WRAP;
	AddressV = WRAP;
};

Texture2D g_tex2;
sampler2D g_sam2 = sampler_state
{
	texture= g_tex2;
	Filter = MIN_MAG_MIP_LINEAR;
	AddressU = WRAP;
	AddressV = WRAP;
};

Texture2D g_tex3;
sampler2D g_sam3 = sampler_state
{
	texture= g_tex3;
	Filter = MIN_MAG_MIP_POINT;
	AddressU = WRAP;
	AddressV = WRAP;
};

//Sampler unit 0
float3 Texture_Unit0(float3 uvw) {

	return (float3)tex2D(g_sam0,uvw.xy);
}

//Sampler unit 1
float3 Texture_Unit1(float3 uvw) {

	return (float3)tex2D(g_sam1,uvw.xy);
}

//Sampler unit 2
float3 Texture_Unit2(float3 uvw) {

	return (float3)tex2D(g_sam2,uvw.xy);
}

//Sampler for procedural base data
float3 Texture_BaseData(float2 uv) {

	return (float3)tex2Dlod(g_sam3,float4(uv,0,0));
}

#define DIRECT_LIGHTS 2
#define OMNI_LIGHTS 2

struct tDirectLight {

	float3 aux;
	float3 color;
	float specular;
	float diffuse;
	float brightness;
};

#ifdef D3D9_IMPL
float4x4 ViewProj;
float3 ViewPosition;
float4x4 World;
float LightFactor = 0.0f;
tDirectLight DirectLight[DIRECT_LIGHTS] = {0};
tDirectLight OmniLight[OMNI_LIGHTS] = {0};
float Time = 0.0f;
float DeformationScale = 0.0f;
#else



cbuffer cbPerFrame {
	float4x4 ViewProj;
	float3 ViewPosition;
	float4x4 World;
	float Time;
	float LightFactor = 0.0f;
	tDirectLight DirectLight[DIRECT_LIGHTS];
	tDirectLight OmniLight[OMNI_LIGHTS];
	float DeformationScale = 0.0f;
};
#endif


void ComputeLighting(float3 wsNormal, float3 wsPosition, float specularScale,
						  out float3 outDiffuse, out float3 outSpecular, out float3 outAmbient) {

	float3 diffuse = (float3)0;
	float specular = 0;
	float3 ambient = (float3).1;

	float3 n = normalize(wsNormal);
	float3 ep = normalize(ViewPosition - wsPosition);
		
	int i;
	for(i = 0; i < DIRECT_LIGHTS; i++) {

		if(any(DirectLight[i].aux)) {

			float3 d = normalize(DirectLight[i].aux);
			
			float3 halfAngle = normalize((ep + d) * 0.5f);
			float brightness = DirectLight[i].brightness;
			
			specular += pow( saturate(dot(n, halfAngle)), 80.0f) * (DirectLight[i].specular * specularScale * brightness);
			diffuse += (float3)saturate(dot(n, d)) * (DirectLight[i].color * DirectLight[i].diffuse * brightness);
		}
	}
	
	for(i = 0; i < OMNI_LIGHTS; i++) {

		if(any(OmniLight[i].aux)) {

			float3 d = normalize(OmniLight[i].aux - wsPosition);
			
			float3 halfAngle = normalize((ep + d) * 0.5f);
			float brightness = OmniLight[i].brightness;
			
			specular += pow( saturate(dot(n, halfAngle)), 80.0f) * (OmniLight[i].specular * specularScale * brightness);
			diffuse += (float3)saturate(dot(n, d)) * (OmniLight[i].color * OmniLight[i].diffuse * brightness);
		}
	}

	outDiffuse =  saturate(diffuse);
	outSpecular = saturate(specular);
	outAmbient = saturate(ambient);
}


#ifdef D3D9_IMPL
#else
RasterizerState DefaultRasterize
{ 
    CULLMODE = D3D10_CULL_NONE;
	FillMode = SOLID;
};

BlendState DefaultBlend
{ 
    BlendEnable[0] = FALSE;
    /*SrcBlend = D3D10_BLEND_SRC_ALPHA;
    DestBlend = D3D10_BLEND_INV_SRC_ALPHA;*/
};

DepthStencilState DefaultDepthStencil
{ 
DepthEnable = TRUE;
DepthWriteMask = ALL;
DepthFunc = LESS_EQUAL;
    
    StencilEnable = False;
};
#endif


#endif
